/**
 * 指令，仅用于ant design vue 中的 dialog 使用
 * 可基于窗口各种拖拽使用
 */

import { App } from "vue";

const drag = {
	mounted(el: any) {
		const dialogs = document.querySelectorAll(".ant-modal");
		const headers = document.querySelectorAll(".ant-modal-header");
		const dialogMasks = document.querySelectorAll(".ant-modal-mask");

		const dialog = dialogs[dialogs.length - 1];
		const header = headers[headers.length - 1];
		const dialogMask = dialogMasks[dialogMasks.length - 1];

		dialogMask.style.cssText += "overflow: hidden;";
		header.style.cursor = "move";

		let dragStatus = false;
		let data = {
			// 数据源，不变部分为：window信息、dialog信息、mouse初始值信息，可变部分为：拖拽坐标位移
			window: {
				// window信息
				width: 0,
				height: 0,
			},
			dialog: {
				x: 0,
				y: 0,
				width: 0,
				height: 0,
				marginTop: "",
			}, // dialog信息
			mouse: {
				// 鼠标初始信息
				x: 0,
				y: 0,
			},
			drag: {
				// 拖拽过程信息
				x: 0,
				y: 0,
			},
		};
		// 所有的监听只为了修改data数据
		header.addEventListener("mousedown", mouseDown);
		document.addEventListener("mousemove", mouseMove);
		document.addEventListener("mouseup", mouseUp);
		window.addEventListener("resize", sizeChange);
		// 边界处理，防止拖动位置溢出
		function handlePosition() {
			if (data.mouse.x - data.drag.x >= data.dialog.x) {
				data.drag.x = data.mouse.x - data.dialog.x;
			}
			if (
				data.drag.x - data.mouse.x >=
				data.window.width - (data.dialog.x + data.dialog.width)
			) {
				data.drag.x =
					data.mouse.x + data.window.width - data.dialog.x - data.dialog.width;
			}
			if (data.mouse.y - data.drag.y >= data.dialog.y) {
				data.drag.y = data.mouse.y - data.dialog.y;
			}
			if (
				data.drag.y - data.mouse.y >=
				data.window.height - (data.dialog.y + data.dialog.height)
			) {
				data.drag.y =
					data.mouse.y +
					data.window.height -
					data.dialog.y -
					data.dialog.height;
			}
			setPosition();
		}
		// 根据data来设置拖动后的位置
		function setPosition() {
			let top = data.drag.y - data.mouse.y + data.dialog.y;
			let left = data.drag.x - data.mouse.x + data.dialog.x;

			dialog.style.cssText += `position: absolute; top: calc(${top}px - ${data.dialog.marginTop}); left: ${left}px;`;
		}
		function mouseDown(e: MouseEvent) {
			// 获取dialog目前的位置，坐标, 以及屏幕当前的宽高
			// 一切初始数据的获取应该放置于此，避免其他如：宽度修改等一系列的影响
			if (e.button !== 0) {
				return;
			}
			data.window = {
				width: document.body.clientWidth,
				height: document.body.clientHeight,
			};


			data.dialog = dialog.getBoundingClientRect();
			data.dialog.marginTop = window.getComputedStyle(dialog).marginTop;
			data.mouse = {
				x: e.clientX,
				y: e.clientY,
			};
			dragStatus = true;
		}
		function mouseMove(e) {
			if (dragStatus) {
				data.drag = {
					x: e.clientX,
					y: e.clientY,
				};

				dialogMask.style.userSelect = "none";
				handlePosition();
			}
		}
		function mouseUp(e: MouseEvent) {
			dialogMask.style.userSelect = "auto";
			dragStatus = false;
		}
		function sizeChange(e: Event) {
			// dialog.style.cssText += 'position: static';
		}
		// 方便卸载使用
		el.__mouseDown__ = mouseDown;
		el.__mouseUp__ = mouseUp;
		el.__mouseMove__ = mouseMove;
		el.__sizeChange__ = sizeChange;
	},
	beforeUnmount(el: any) {
		// 避免重复开销，卸载所有的监听
		// 解决问题：多次创建新的实例 =》 监听不取消 =》 同时存在多个无用的监听，导致页面卡顿
		document.removeEventListener("mousedown", el.__mouseDown__);
		document.removeEventListener("mousemove", el.__mouseMove__);
		document.removeEventListener("mouseup", el.__mouseUp__);
		window.removeEventListener("resize", el.__sizeChange__);
	},
};

export const antModalDrag = {
	install(app: App) {
		app.directive("ant-modal-drag", drag);
	},
};

export default drag;